#include "Beat.h"
#include <math.h>
#include <FL/fl_ask.H>
#include <FL/Fl_Value_Slider.H>

#define NUMBER_OF_PARAMS 2

#define GAIN        0
#define SPEED       1


Beat::Beat()
{
    numOfParams = NUMBER_OF_PARAMS;

    params = new double[numOfParams];

    params[GAIN]    = 0.3;
    params[SPEED]   = 0.9999;

    freq = 10.0;
    oscRad = 0;
    bIsPolyphonic = true;

   /* for (int i=0; i<numOfParams; i++)
    {
        EnvelopeEquation e = EnvelopeEquation();
        envelopeEquations.push_back(e);
    }
*/

}


void Beat::initMaster()
{

//        songEnvelopes[GAIN]->points->insert(Point(0.0 , 01.0));
     //   songEnvelopes[GAIN]->points->insert(Point(22220.0 , 02.0));
    //    songEnvelopes[GAIN]->points->insert(Point(4400.0 , 06.90));

}


void Beat::newSlave()
{
    Beat *slave = new Beat();
    slaves.push_back(slave);
}

void Beat::handleEvent( pluginEvent* event )    //this gets called just before process buffer if there are any events
{
    switch ( event->eventType )
    {
    case EVT_NOTE_ON:
        oscRad = 0;
        samplesSinceNoteStart = 0;
        amplitude = params[GAIN];
        bIsFree = false;
        //params[FREQ] = event->data->gain * 15.0 + 5.0;
        freq = event->data->gain * 0.5 + 2.0;
        params[SPEED] = 0.999 + event->data->speed / 10000;
        fade = 0.99999;
        break;
    case EVT_NOTE_OFF:
        fade = 0.9999;
      //  fl_alert("no");
        //bIsFree=false;
        //amplitude = 0;
        break;
    }
}

void Beat::isFree()
{
    if (amplitude < 0.01)
        bIsFree = true;
}

void Beat::processBuffer( float *outputBuffer, unsigned long framesPerBuffer)
{
    float loop = 256 * M_PI;
    if (oscRad >= loop) oscRad -= loop;

    float outSamp;

    for( unsigned long i=0; i<framesPerBuffer; i++, totalSamples++, samplesSinceNoteStart++ )
    {
        amplitude *= fade;
        //freq *= songEnvelopes[SPEED]->getValue(totalSamples);
        //freq *= getValue(SPEED);
        //freq = getValue(SPEED);
        oscRad += (freq + getValue(GAIN))/ 100.0f;
        //oscRad += (freq )/ 100.0f;
        //params[FREQ] = params[FREQ] * params[SPEED];

        outSamp = amplitude  * sin(oscRad)/4;
        *outputBuffer++ += outSamp;
        *outputBuffer++ += outSamp; // right
    }
}

Fl_Widget * Beat::displayWindow()
{
    //Fl_Button * o = new Fl_Button(30, 36, 22,22,"d");

    Fl_Value_Slider * o = new Fl_Value_Slider(120, 60, 133, 120, "FG Bright");
    o->align(FL_ALIGN_LEFT);
    o->type(FL_HOR_SLIDER);
    o->bounds(0.0, 1.0);
    o->value(1.0);
    o->callback(gainChanged_CB, (void*)this);

    return o;
}


void Beat::gainChanged_CB(Fl_Widget* w, void*userdata)
{
    Beat *plugin = (Beat*)userdata;
    plugin->params[GAIN] = ((Fl_Value_Slider*)w)->value();
}
